package com.dc.common.aspectj;

import com.dc.common.annotation.DataScope;
import com.dc.common.constant.CustomConstants;
import com.dc.common.core.LoginRole;
import com.dc.common.core.LoginUser;
import com.dc.common.core.PageParamDto;
import com.dc.common.utils.ShiroUtil;
import com.dc.common.utils.StringUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * 数据过滤处理
 *
 * @author ruoyi
 */
@Aspect
@Component
public class DataScopeAspect {
    /**
     * 全部数据权限
     */
    public static final String DATA_SCOPE_ALL = "1";

    /**
     * 自定数据权限
     */
    public static final String DATA_SCOPE_CUSTOM = "2";

    /**
     * 部门数据权限
     */
    public static final String DATA_SCOPE_DEPT = "3";

    /**
     * 部门及以下数据权限
     */
    public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";

    /**
     * 仅本人数据权限
     */
    public static final String DATA_SCOPE_SELF = "5";

    /**
     * 数据权限过滤关键字
     */
    public static final String DATA_SCOPE = "dataScope";
    public static final String DATA_SCOPE_SQL = "dataScopeSql";

    /**
     * 配置织入点
     */
    @Pointcut("@annotation(com.dc.common.annotation.DataScope)")
    public void dataScopePointCut() {
    }

    @Before("dataScopePointCut()")
    public void doBefore(JoinPoint point) {
        // 获得注解
        DataScope controllerDataScope = getAnnotationLog(point);
        if (controllerDataScope == null) {
            return;
        }
        // 获取当前的用户
        LoginUser loginUser = ShiroUtil.getUserInfo();
        dataScopeFilter(point, loginUser, controllerDataScope);
    }


    /**
     * 数据范围过滤
     *
     * @param joinPoint           切点
     * @param user                用户
     * @param controllerDataScope 注解
     */
    public static void dataScopeFilter(JoinPoint joinPoint, LoginUser user, DataScope controllerDataScope) {
        StringBuilder sqlString = new StringBuilder();
        // 如果不是超级管理员，则过滤数据
        if (!Arrays.asList(CustomConstants.SUPER_ADMIN).contains(user.getAccount())) {
            String userColumn = StringUtil.isEmpty(controllerDataScope.userColumn()) ? "created_id" : controllerDataScope.userColumn();
            String userAlias = StringUtil.isEmpty(controllerDataScope.userPrefix()) ? StringUtil.EMPTY : StringUtil.format("{}.", controllerDataScope.userPrefix());
            List<LoginRole> loginRoles = user.getLoginRoles();
            if (loginRoles != null && !loginRoles.isEmpty()) {
                for (LoginRole role : loginRoles) {
                    String dataScope = role.getDataScope();
                    if (DATA_SCOPE_ALL.equals(dataScope)) {
                        // 全部数据权限
                        sqlString = new StringBuilder();
                        break;
                    } else if (DATA_SCOPE_CUSTOM.equals(dataScope)) {
                        // 自定义数据权限
                        sqlString.append(StringUtil.format(
                                " or {}{} in ( select user_id from sys_user du join sys_role_dept drd on du.dept_id=drd.dept_id and role_id = {} ) ",
                                userAlias, userColumn, role.getRoleId()));
                    } else if (DATA_SCOPE_DEPT.equals(dataScope)) {
                        // 本部门数据权限
                        sqlString.append(StringUtil.format(
                                " or {}{} in ( select user_id from sys_user du join sys_dept dd on du.dept_id=dd.dept_id and dd.dept_id = {} ) ",
                                userAlias, userColumn, user.getDeptId()));
                    } else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) {
                        // 部门及部门以下数据权限
                        sqlString.append(StringUtil.format(
                                " or {}{} in ( select user_id from sys_user du join sys_dept dd on dd.dept_id=du.dept_id and (dd.dept_id = {} or find_in_set({} , ancestors )))",
                                userAlias, userColumn, user.getDeptId(), user.getDeptId()));
                    } else if (DATA_SCOPE_SELF.equals(dataScope)) {
                        //仅本人数据权限
                        sqlString.append(StringUtil.format(" or {}{} = {} ", userAlias, userColumn, user.getUserId()));
                    }
                }
            } else {
                sqlString.append(" or  1=0 ");
            }
        } else {
            sqlString.append(" or  1=1 ");
        }

        if (StringUtil.isNotBlank(sqlString.toString())) {
            Object[] args = joinPoint.getArgs();
            for (Object params : args) {
                if (StringUtil.isNotNull(params) && params instanceof PageParamDto) {
                    PageParamDto baseEntity = (PageParamDto) params;
                    baseEntity.getParams().put(DATA_SCOPE, " and (" + sqlString.substring(4) + ")");
                    baseEntity.getParams().put(DATA_SCOPE_SQL, sqlString.substring(4));
                    break;
                }
            }

        }
    }

    /**
     * 是否存在注解，如果存在就获取
     */
    private DataScope getAnnotationLog(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null) {
            return method.getAnnotation(DataScope.class);
        }
        return null;
    }
}
